package cn.edu.hitwh.kanlema.listener;

import cn.edu.hitwh.kanlema.constant.MqConstants;
import cn.edu.hitwh.kanlema.constant.RedisConstants;
import cn.edu.hitwh.kanlema.entity.Cinema;
import cn.edu.hitwh.kanlema.entity.CinemaType;
import cn.edu.hitwh.kanlema.message.RebuildCacheMessage;
import cn.edu.hitwh.kanlema.service.ICinemaService;
import cn.edu.hitwh.kanlema.service.ICinemaTypeService;
import cn.edu.hitwh.kanlema.util.RedisCache;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class HotKeyRebuildListener {
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ICinemaTypeService cinemaTypeService;

    @Autowired
    private ICinemaService cinemaService;


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(MqConstants.CINEMA_TYPE_REBUILD_QUEUE),
            exchange = @Exchange(MqConstants.HOT_KEY_REBUILD_EXCHANGE),
            key = MqConstants.CINEMA_TYPE_REBUILD_KEY
    ))
    public void rebuildCinemaType(RebuildCacheMessage message) {
        String cacheKey = message.getCacheKey();
        String lockKey = message.getLockKey();
        List<CinemaType> list = cinemaTypeService
                .lambdaQuery()
                .orderByAsc(CinemaType::getSort)
                .list();
        redisCache.setWithLogicalExpire(cacheKey, JSONUtil.toJsonStr(list),
                RedisConstants.CACHE_CINEMA_TYPE_TTL, TimeUnit.MINUTES);
        redisCache.unlock(lockKey);
        log.debug("rebuild cinema type cache success");
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(MqConstants.HOT_CINEMA_REBUILD_QUEUE),
            exchange = @Exchange(MqConstants.HOT_KEY_REBUILD_EXCHANGE),
            key = MqConstants.HOT_CINEMA_REBUILD_KEY
    ))
    public void rebuildHotCinema(RebuildCacheMessage message) {
        String cacheKey = message.getCacheKey();
        String lockKey = message.getLockKey();

        Long cinemaId = Long.parseLong(cacheKey.substring(cacheKey.lastIndexOf(':') + 1));
        Cinema cinema = cinemaService.lambdaQuery()
                        .eq(Cinema::getId, cinemaId)
                        .one();

        if (cinema != null) {
            redisCache.setWithLogicalExpire(cacheKey, JSONUtil.toJsonStr(cinema),
                    RedisConstants.CACHE_HOT_CINEMA_TTL, TimeUnit.MINUTES);
        } else {
            cinemaService.setCinemaHot(cinemaId, false);
            log.warn("cinema {} not found, set hot to false", cinemaId);
        }

        redisCache.unlock(lockKey);
        log.debug("rebuild hot cinema cache success");
    }
}
